﻿// Deep Earth is a community project available under the Microsoft Public License (Ms-PL)
// Code is provided as is and with no warrenty – Use at your own risk
// View the project and the latest code at http://DeepEarth.codeplex.com/


using System.Windows;
using DeepEarth.Toolkit.Common;
using System.Windows.Controls.Primitives;
using System.Windows.Controls;
using System.ComponentModel;
using System.Windows.Input;
using System.Collections.Generic;
using System;

namespace DeepEarth.Toolkit.Controls
{
    [TemplatePart(Name = PART_zoomInButton, Type = typeof(RepeatButton))]
    [TemplatePart(Name = PART_zoomOutButton, Type = typeof(RepeatButton))]
    [TemplatePart(Name = PART_rightButton, Type = typeof(RepeatButton))]
    [TemplatePart(Name = PART_downButton, Type = typeof(RepeatButton))]
    [TemplatePart(Name = PART_leftButton, Type = typeof(RepeatButton))]
    [TemplatePart(Name = PART_upButton, Type = typeof(RepeatButton))]
    [TemplatePart(Name = PART_spinButton, Type = typeof(Button))]
    [TemplatePart(Name = PART_HorizontalPanel, Type = typeof(StackPanel))]
    [TemplatePart(Name = PART_VerticalPanel, Type = typeof(StackPanel))]
    [TemplateVisualState(GroupName = WindowStateGroupName, Name = CollapsedStateName)]
    [TemplateVisualState(GroupName = WindowStateGroupName, Name = ExpandedStateName)]
    [TemplateVisualState(GroupName = MouseStateGroupName, Name = MouseEnterStateName)]
    [TemplateVisualState(GroupName = MouseStateGroupName, Name = MouseLeaveStateName)]
    public class NavigationPanel : MapInteractionControl
    {
        #region PART names
        const string PART_rightButton = "PART_rightButton";
        const string PART_downButton = "PART_downButton";
        const string PART_leftButton = "PART_leftButton";
        const string PART_upButton = "PART_upButton";
        const string PART_spinButton = "PART_spinButton";
        const string PART_zoomInButton = "PART_zoomInButton";
        const string PART_zoomOutButton = "PART_zoomOutButton";
        const string PART_HorizontalPanel = "PART_HorizontalPanel";
        const string PART_VerticalPanel = "PART_VerticalPanel";
        #endregion

        #region State Definitions
        const string MouseStateGroupName = "MouseStateGroup";
        const string MouseEnterStateName = "MouseEnter";
        const string MouseLeaveStateName = "MouseLeave";

        const string WindowStateGroupName = "WindowStateGroup";
        const string CollapsedStateName = "Collapsed";
        const string ExpandedStateName = "Expanded";
        #endregion


        private const int PanAmount = 250;

        RepeatButton downButton, leftButton, rightButton, upButton, zoomInButton, zoomOutButton;
        Button spinButton;
        StackPanel horizontalPanel, verticalPanel;

        public NavigationPanel()
        {
            this.DefaultStyleKey = typeof(NavigationPanel);

            MouseEnter += (o, mea) => SetMouseState(true);
            MouseLeave += (o, mea) => SetMouseState(false);
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            if (!DesignerProperties.IsInDesignTool)
            {
                rightButton = (RepeatButton)GetTemplateChild(PART_rightButton);
                downButton = (RepeatButton)GetTemplateChild(PART_downButton);
                leftButton = (RepeatButton)GetTemplateChild(PART_leftButton);
                upButton = (RepeatButton)GetTemplateChild(PART_upButton);
                zoomOutButton = (RepeatButton)GetTemplateChild(PART_zoomOutButton);
                zoomInButton = (RepeatButton)GetTemplateChild(PART_zoomInButton);
                spinButton = (Button)GetTemplateChild(PART_spinButton);

                horizontalPanel = (StackPanel)GetTemplateChild(PART_HorizontalPanel);
                verticalPanel = (StackPanel)GetTemplateChild(PART_VerticalPanel);

                // TODO: Expose a PanCommand from the map and bind to that instead
                rightButton.Click += (e, o) => PanMap(PanAmount, 0);
                downButton.Click += (e, o) => PanMap(0, PanAmount);
                leftButton.Click += (e, o) => PanMap(-PanAmount, 0);
                upButton.Click += (e, o) => PanMap(0, -PanAmount);


                zoomOutButton.Click += (o, e) => ZoomMap(-1);
                zoomInButton.Click += (o, e) => ZoomMap(1);

                spinButton.Click += (e, o) => SetExpandedState(IsCollapsed = !IsCollapsed);

                SetExpandedState(this.IsCollapsed);

                ExecutePostInitializationActions();                
            }
        }

        List<Action> postInitializationActions = new List<Action>();

        private void ExecutePostInitializationActions()
        {
            foreach (Action action in postInitializationActions)
            {
                action();
            }

            postInitializationActions.Clear();
        }

        #region Properties



        public UIElement HorizontalPanel
        {
            get
            {
                return horizontalPanel;
            }
            set
            {
                if (horizontalPanel == null)
                {
                    postInitializationActions.Add(() => horizontalPanel.Children.Add(value));
                }
                else
                {
                    horizontalPanel.Children.Add(value);
                }
            }
        }

        public UIElement VerticalPanel
        {
            get
            {
                return verticalPanel;
            }
            set
            {
                if (verticalPanel == null)
                {
                    postInitializationActions.Add(() => verticalPanel.Children.Add(value));
                }
                else
                {
                    verticalPanel.Children.Add(value);
                }
            }
        }

        public static readonly DependencyProperty HorizontalToolBarLeftProperty =
            DependencyProperty.Register("HorizontalToolBarLeft",
                                typeof(double),
                                typeof(NavigationPanel),
                                null);

        public double HorizontalToolBarLeft
        {
            get
            {
                return (double)GetValue(HorizontalToolBarLeftProperty);
            }
            set
            {
                SetValue(HorizontalToolBarLeftProperty, value);
            }
        }

        public static readonly DependencyProperty NavCircleScaleProperty =
            DependencyProperty.Register("NavCircleScale",
                                        typeof(double),
                                        typeof(NavigationPanel),
                                        null);

        public double NavCircleScale
        {
            get
            {
                return (double) GetValue(NavCircleScaleProperty);
            }
            set
            {
                SetValue(NavCircleScaleProperty, value);
            }
        }

        public static readonly DependencyProperty VerticalToolBarTopProperty =
            DependencyProperty.Register("VerticalToolBarTop",
                                        typeof(double),
                                        typeof(NavigationPanel),
                                        null);


        public double VerticalToolBarTop
        {
            get
            {
                return (double)GetValue(VerticalToolBarTopProperty);
            }
            set
            {
                SetValue(VerticalToolBarTopProperty, value);
            }
        }


        public static readonly DependencyProperty IsCollapsedProperty = DependencyProperty.Register("IsCollapsed", typeof(bool), typeof(NavigationPanel),
            new PropertyMetadata(false, (d, e) => ((NavigationPanel)d).OnIsCollapsedChanged((bool)e.OldValue, (bool)e.NewValue)));
        public bool IsCollapsed
        {
            get { return (bool)GetValue(IsCollapsedProperty); }
            set { SetValue(IsCollapsedProperty, value); }
        }

        void OnIsCollapsedChanged(bool oldValue, bool newValue)
        {
            SetExpandedState(newValue);
        }

        public static readonly DependencyProperty HorizontalToolBarContentTemplateProperty = DependencyProperty.Register("HorizontalToolBarContentTemplate", typeof(object), typeof(NavigationPanel), null);
        public object HorizontalToolBarContentTemplate
        {
            get { return GetValue(HorizontalToolBarContentTemplateProperty); }
            set { SetValue(HorizontalToolBarContentTemplateProperty, value); }
        }

        public static readonly DependencyProperty VerticalToolBarContentTemplateProperty = DependencyProperty.Register("VerticalToolBarContentTemplate", typeof(object), typeof(NavigationPanel), null);
        public object VerticalToolBarContentTemplate
        {
            get { return GetValue(VerticalToolBarContentTemplateProperty); }
            set { SetValue(VerticalToolBarContentTemplateProperty, value); }
        }
        #endregion

        private void PanMap(int deltaX, int deltaY)
        {

            Map.Pan(deltaX, deltaY);
        }

        private void ZoomMap(int delta)
        {
            Map.Zoom(delta);
        }

        void SetMouseState(bool newValue)
        {
            VisualStateManager.GoToState(this, newValue ? MouseEnterStateName : MouseLeaveStateName, true);
        }

        void SetExpandedState(bool newValue)
        {
            VisualStateManager.GoToState(this, newValue ? CollapsedStateName : ExpandedStateName, true);
        }

    }
}